/// by Alvaro Cuno, Fev2008

#ifndef __RBF_MESHDEF_GL_H__
#define __RBF_MESHDEF_GL_H__

#include "rbfEvalKernel_3to3.h"
#include "mesh.h"

#include <iterator>

class RbfMeshDefGl: public RbfEvalKernel3to3 {
   
public:
   RbfMeshDefGl() :
      RbfEvalKernel3to3() {
      model = 0;
   }
   
   RbfMeshDefGl(Mesh *m) :
      RbfEvalKernel3to3() {
      assert(m != 0);
      model = m;
   }
   
   virtual ~RbfMeshDefGl() {
   }
   
   void setMesh(Mesh *m) {
      assert(m != 0);
      model = m;
   }

   void setting(vector<Point3> &centers) {
      
      assert(model != 0);
      
      ipositions.resize(model->nvertices());
      inormals.resize(model->nvertices());
      for (uint i=0; i<ipositions.size(); ++i) {
         ipositions[i] = model->positions[i];
         inormals[i] = model->normals[i];
      }
      
      // compute the rbf inverse matrix
      compute_iM(centers);
      //~ cout<<iM<<endl;
      
      // set the evaluation point and install the kernel
      setEvalPoints(ipositions);
   }
   
   void execute_deformation(vector<Point3> &fcenters) {
      
      genWeights(fcenters);
      
      int N = (int)(ceil(sqrt(ipositions.size())));
      vector<Point3> result(N*N);
      execute(result);
      
      addPolynomialTerm(result);
      
      for (uint i=0; i<model->nvertices(); ++i) {
         model->positions[i] = result[i];
      }
   }
   
private:
   Mesh                   *model;
   vector<Point3>         ipositions; // initial vertex positions
   vector<Vector3>        inormals;   // initial vertex normal
};

#endif 
